package com.infinitus.autocatlog.service.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.infinitus.autocatlog.domain.KafkaStartupLog;
import com.infinitus.autocatlog.domain.FilterCountLog;
import com.infinitus.autocatlog.domain.FilterLog;
import com.infinitus.autocatlog.domain.RecordItem;
import com.infinitus.autocatlog.service.KafkaLogService;
import com.infinitus.autocatlog.service.util.TimeUtil;
import com.infinitus.autocatlog.task.FilterRules;



@Service
public class KafkaLogServiceImpl implements KafkaLogService {

//	@PersistenceContext
//	private EntityManager entityManager;
	@Autowired
	private EntityManagerFactory entityManagerFactory;


	@Override
	@Transactional
	public void addFilterLog(FilterLog filterLog) {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		try{
			entityManager.merge(filterLog);
			entityManager.flush();
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally {
			entityManager.clear();
			entityManager.close();
		}
	}
	
	
	@Override
	@Transactional
	public void saveCountLog(FilterCountLog countLog) {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		try{
			Date the_date = countLog.getTheDate();
			if(the_date==null){
				the_date = new Date();
			}
			
			try {
				the_date = TimeUtil.dateFormat.parse(TimeUtil.dateFormat.format(the_date));
			} catch (ParseException e) {
				e.printStackTrace();
			}
			
			List<FilterCountLog> resultList = entityManager.createNamedQuery("FilterCountLog.findByDateAndTopic",FilterCountLog.class ).setParameter("theDate", the_date).setParameter("receiverTopic", countLog.getReceiverTopic()).getResultList();
			
			if(resultList.size() == 0) {
				entityManager.merge(countLog);
			} else {
				countLog.setId(resultList.get(0).getId());
				entityManager.merge(countLog);
			}
			entityManager.flush();
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally {
			entityManager.clear();
			entityManager.close();
		}
	}
	
	@Override
	public void saveFilterLog(FilterLog filterLog) {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		try{
			List<FilterLog> resultList = entityManager.createNamedQuery("FilterLog.findUnique",FilterLog.class )
					.setParameter("ReceiverTopic", filterLog.getReceiverTopic()).setParameter("OsPlat", filterLog.getOsPlat())
					.setParameter("ReceiverDate", filterLog.getReceiverDate()).setParameter("ReceiverHour", filterLog.getReceiverHour())
					.setParameter("EventDate", filterLog.getEventDate()).setParameter("SystemName", filterLog.getSystemName())
					.setParameter("FilterType", filterLog.getFilterType()).getResultList();
			if(resultList.size() == 0) {
				entityManager.merge(filterLog);
			} else {
				filterLog.setId(resultList.get(0).getId());
				entityManager.merge(filterLog);
			}
			entityManager.flush();
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally {
			entityManager.clear();
			entityManager.close();
		}
		
	}
	
	private void setParams(Query nativeQuery, Map<String, Object> paramMap) {
		for(Entry<String, Object> entry:  paramMap.entrySet()){
			nativeQuery.setParameter(entry.getKey(), entry.getValue());
		}
	}



	@Override
	@Transactional
	public void saveLog(RecordItem recordItem) {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		try{
			entityManager.merge(recordItem);
			entityManager.flush();
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally {
			entityManager.clear();
			entityManager.close();
		}
	}


	


	@Override
	public Map<String, Object> loadLogInfo() {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		Map<String, Object> map = new HashMap<String, Object>();
		List<String> res = entityManager.createNamedQuery("FilterCountLog.findDate").getResultList();
		String startTime = "";
		String endTime = "";
		if(res!=null && res.size()>0){
			startTime = res.get(0);
			endTime = res.get(res.size()-1);
		}
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		entityManager.clear();
		entityManager.close();
		return map;
	}


	@Override
	public List<FilterCountLog> findAllFilterLog() {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		List<FilterCountLog> filterLogs =  entityManager.createNamedQuery("FilterCountLog.findAll",FilterCountLog.class).getResultList();
		entityManager.clear();
		entityManager.close();
		return filterLogs;
	}


	@Override
	public FilterCountLog getFilterCountLog(Map<String, Object> params) {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		String addTime = (String) params.get("addTime");
		if(!FilterRules.isNotBlank(addTime)){
			return null;
		}
		FilterCountLog filterCountLog = null;
		try {
			List<FilterCountLog> fclRes= entityManager.createNamedQuery("FilterCountLog.findByDate",FilterCountLog.class).setParameter("theDate", TimeUtil.dateFormat.parse(addTime)).getResultList();
			if(fclRes!=null && fclRes.size()>0){
				filterCountLog = fclRes.get(0);
				int totalCount =0;
				for(FilterCountLog fcl : fclRes){
					totalCount+=fcl.getTotalCount();
				}
				filterCountLog.setTotalCount(totalCount);
			}else{
				filterCountLog = new FilterCountLog();
				filterCountLog.setTotalCount(0);
			}
			
			List ecRes = entityManager.createNamedQuery("FilterDetailLog.countByDate").setParameter("addTime", addTime).getResultList();
			if(ecRes!=null && ecRes.size()>0){
				filterCountLog.setErrorCount(Integer.parseInt(""+ecRes.get(0)));
			}else{
				filterCountLog.setErrorCount(0);
			}
			
			List<Object[]> tccRes = entityManager.createNativeQuery("select total_count, error_count from crash_count_log where the_date = :the_date").setParameter("the_date", addTime).getResultList();
			if(tccRes!=null && tccRes.size()>0){
				filterCountLog.setTotalCrashCount(tccRes.get(0)[0]+"");
				filterCountLog.setTotalCrashCount(tccRes.get(0)[1]+"");
			}else{
				filterCountLog.setTotalCrashCount("0");
				filterCountLog.setErrorCrashCount("0");
			}
			
			/*List eccRes = entityManager.createNamedQuery("CrashErrorLog.countByDate").setParameter("addTime", addTime).getResultList();
			if(eccRes!=null && eccRes.size()>0){
				filterCountLog.setErrorCrashCount(eccRes.get(0)+"");
			}else{
				filterCountLog.setErrorCrashCount("0");
			}*/
		} catch (ParseException e) {
			e.printStackTrace();
		}
		entityManager.clear();
		entityManager.close();
		return filterCountLog;
	}

	
	@Override
	@Transactional
	public void addStartupLog(KafkaStartupLog startupLog) {
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		try{
			entityManager.merge(startupLog);
			entityManager.flush();
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally {
			entityManager.clear();
			entityManager.close();
		}
	}


}
